package org.hrqing.authorization.security;

import lombok.*;
import org.hrqing.authorization.entity.Role;
import org.hrqing.authorization.entity.User;
import org.hrqing.authorization.entity.UserRole;
import org.hrqing.authorization.mapstruct.UserConvertMapper;
import org.hrqing.authorization.repo.RoleRepo;
import org.hrqing.authorization.repo.UserRepo;
import org.hrqing.authorization.repo.UserRoleRepo;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @auther Hrqing
 */
@RequiredArgsConstructor
public class JpaUserDetailsService implements UserDetailsService {

    private final UserRepo userRepo;
    private final UserRoleRepo userRoleRepo;
    private final RoleRepo roleRepo;

    @Override
    public SecurityUser loadUserByUsername(String username) throws AuthenticationException {
        Optional<User> repo = userRepo.findByUsernameOrCertNumberOrMobile(username.trim(), username.trim(), username.trim());
        if (repo.isEmpty()) {
            throw new UsernameNotFoundException(username);
        }
        User user = repo.get();
        if (!user.isEnabled()) {
            throw new DisabledException(username + " is disabled");
        }
        List<UserRole> userRoles = userRoleRepo.findByUserId(user.getId());
        List<Role> roles = roleRepo.findAllById(userRoles.stream().map(UserRole::getRoleId).toList());
        List<SimpleGrantedAuthority> authorities = roles.stream().map(mapper -> new SimpleGrantedAuthority(mapper.getName())).toList();
        return UserConvertMapper.INSTANCE.convertUserToSecurityUser(user, authorities);
    }
}
